package net.wofly.sale.commodity.web;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.github.stuxuhai.jpinyin.PinyinException;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.wofly.common.condition.Condition;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.ExcelUtil;
import net.wofly.common.web.BaseController;
import net.wofly.framework.util.ReturnBean;
import net.wofly.sale.commodity.domain.Brand;
import net.wofly.sale.commodity.domain.Commodity;
import net.wofly.sale.commodity.domain.CommodityChannel;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.commodity.domain.CommodityTerminalView;
import net.wofly.sale.commodity.domain.CommodityType;
import net.wofly.sale.commodity.dto.CommodityDto;
import net.wofly.sale.commodity.service.IBrandService;
import net.wofly.sale.commodity.service.ICommodityChannelService;
import net.wofly.sale.commodity.service.ICommodityService;
import net.wofly.sale.commodity.service.ICommodityTmlService;
import net.wofly.sale.commodity.service.ICommodityTypeService;
import net.wofly.sale.commodity.validator.CommodityValidator;

/**
 * @author siqingwei
 */
@RestController
@RequestMapping("/api/commodity")
@Api(description = "商品接口")
public class CommodityController extends BaseController{

	private static final Logger logger = LoggerFactory.getLogger(CommodityController.class);

	@Resource
	ICommodityService iCommodityService;
	@Resource
	ICommodityChannelService iCommodityChannelService;
	@Resource
	ICommodityTmlService iCommodityTmlService;
	
	@Resource
	IBrandService iBrandService;
	
	@Resource
	ICommodityTypeService iCommodityTypeService ;

	/**
	 * 添加商品
	 * <ul>
	 * 	<li>添加时需要验证商品编码是否存在，如果存在则提示用户</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityDto
	 * @throws PinyinException 
	 */
	@ApiOperation(value = "添加商品", notes = "添加商品")
	@ApiImplicitParam(name = "commodityDto", value = "商品信息实体", required = true, dataType = "CommodityDto")
	@RequestMapping(value = "/addCommodity", method = { RequestMethod.POST })
	public ReturnBean<Commodity> addCommodity(@RequestBody CommodityDto commodityDto) throws PinyinException{
		ReturnBean<Commodity> returnBean;

		String errorMessage = CommodityValidator.validateAddCommodityParams(commodityDto);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.addCommodity(commodityDto);
		}
		return returnBean;
	}

	/**
	 * 添加商品渠道编码及价格
	 * <ul>
	 * 	<li>验证渠道编码是否重复</li>
	 * </ul>
	 *
	 * @param commodityChannel
	 */
	@ApiOperation(value = "添加商品渠道编码及价格", notes = "添加商品渠道编码及价格")
	@ApiImplicitParam(name = "commodityChannel", value = "商品渠道实体", required = true, dataType = "CommodityChannel")
	@RequestMapping(value = "/addCommodityChannel", method = { RequestMethod.POST})
	public ReturnBean<CommodityChannel> addCommodityChannel(@RequestBody CommodityChannel commodityChannel){
		ReturnBean<CommodityChannel> returnBean;

		String errorMessage = CommodityValidator.validateAddCommodityChannelParams(commodityChannel);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.addCommodityChannel(commodityChannel);
		}
		return returnBean;
	}

	/**
	 * 删除商品
	 * <ul>
	 * 	<li>只是将商品 状态置为无效</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityID
	 */
	@ApiOperation(value = "删除商品", notes = "删除商品")
	@ApiImplicitParam(name = "commodityID", value = "商品ID", required = true, dataType = "String", paramType = "form")
	@RequestMapping(value = "/delCommodity", method = { RequestMethod.POST })
	public ReturnBean<String> delCommodity(String commodityID){
		ReturnBean<String> returnBean;

		String errorMessage = CommodityValidator.validateDelCommodityParams(commodityID);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.delCommodity(commodityID);
		}
		return returnBean;
	}

	/**
	 * 删除商品渠道编码及价格
	 * <ul>
	 * 	<li>验证商品渠道编码置为无效</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityChannelID
	 */
	@ApiOperation(value = "删除商品渠道编码及价格", notes = "删除商品渠道编码及价格")
	@ApiImplicitParam(name = "commodityChannelID", value = "商品渠道ID", required = true, dataType = "String", paramType = "form")
	@RequestMapping(value = "/delCommodityChannel", method = { RequestMethod.POST})
	public ReturnBean<String> delCommodityChannel(String commodityChannelID){
		ReturnBean<String> returnBean;

		String errorMessage = CommodityValidator.validateDelCommodityChannelParams(commodityChannelID);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.delCommodityChannel(commodityChannelID);
		}
		return returnBean;
	}

	/**
	 * 获取商品的所有渠道价格
	 */
	//@RequiresPermissions(value = "/api/commodity/getAllCommodityChannel")
	@ApiOperation(value = "获取商品的所有渠道价格", notes = "获取商品的所有渠道价格")
	@ApiImplicitParams({@ApiImplicitParam(name = "condition", value = "查询条件", required = false, dataType = "String", paramType = "form"),
			@ApiImplicitParam(name = "pageNum", value = "第几页", required = true, dataType = "Integer", paramType = "form"),
			@ApiImplicitParam(name = "pageSize", value = "每页多少条", required = true, dataType = "Integer", paramType = "form")})
	@RequestMapping(value = "/getAllCommodityChannel", method = { RequestMethod.GET })
	public ReturnBean<PageWrapper<Commodity>> getAllCommodityChannel(@RequestParam(defaultValue = "1", name = "pageNum") Integer pageNum,
																	 @RequestParam(defaultValue = "20", name = "pageSize") Integer pageSize,
																	 String condition){
		ReturnBean<PageWrapper<Commodity>> returnBean;

		String errorMessage = CommodityValidator.validateGetAllCommodityChannelParams();
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.getAllCommodityChannel(pageNum, pageSize, JSON.parseObject(condition, Condition.class));
		}
		return returnBean;
	}

	/**
	 * 通过商品类型获取商品列表
	 * <ul>
	 * 	<li>flag=1时只取所有分类下有效的商品；flag=0时取所有无效商品；flag=-1时，取所有商品。</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityTypeID
	 * @param flag
	 */
	//@RequiresUser
	//@RequiresPermissions(value = "/api/commodity/getCommodityByType")
	@ApiOperation(value = "通过商品类型获取商品列表", notes = "通过商品类型获取商品列表")
	@ApiImplicitParams({@ApiImplicitParam(name = "commodityTypeID", value = "商品类型ID", required = true,dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "flag", value = "商品是否有效，flag=1时只取所有分类下有效的商品；flag=0时取所有无效商品；flag=-1时，取所有商品。",required = false, dataType = "Integer", paramType = "query")})
	@RequestMapping(value = "/getCommodityByType", method = { RequestMethod.GET })
	public ReturnBean<List<Commodity>> getCommodityByType(String commodityTypeID, Integer flag){
		ReturnBean<List<Commodity>> returnBean;
		
		String errorMessage = CommodityValidator.validateGetCommodityByTypeParams(commodityTypeID, flag);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.getCommodityByType(commodityTypeID, flag);
		}
		return returnBean;
	}
	
	/**
	 * 分页获取商品列表
	 * <ul>
	 * 	<li></li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityTypeID
	 * @param flag
	 */
	//@RequiresUser
	//@RequiresPermissions(value = "/api/commodity/getCommodityByType")
	@ApiOperation(value = "分页获取商品列表", notes = "分页获取商品列表")
	@ApiImplicitParams({@ApiImplicitParam(name = "commodityName", value = "商品名称", required = false,dataType = "String", paramType = "form"),
						@ApiImplicitParam(name = "commodityTypeID", value = "商品类型ID", required = false,dataType = "String", paramType = "form"),
						@ApiImplicitParam(name = "status", value = "商品是否有效，flag=1时只取所有分类下有效的商品；flag=0时取所有无效商品；flag=-1时，取所有商品。",required = false, dataType = "Integer", paramType = "form"),
						@ApiImplicitParam(name = "pageNum", value = "第几页", required = false, dataType = "Integer", paramType = "form"),
						@ApiImplicitParam(name = "pageSize", value = "每页多少条", required = false, dataType = "Integer", paramType = "form")})
	@RequestMapping(value = "/getCommodityByPage", method = { RequestMethod.POST })
	public ReturnBean<PageWrapper<Commodity>> getCommodityByPage(String commodityName,String commodityTypeID, @RequestParam(defaultValue = "1", name = "status")int status,@RequestParam(defaultValue = "1", name = "pageNum")int pageNum, @RequestParam(defaultValue = "10", name = "pageSize")int pageSize){
		
		return new ReturnBean<>(ReturnBean.CODE_SUCCESS, "分页获取商品列表成功！" ,iCommodityService.getCommodityByPage(commodityName, commodityTypeID, status, pageNum, pageSize));
	}

	@ApiOperation(value = "导出商品列表", notes = "导出商品列表")
	@RequestMapping(value = "/exportCommodity", method = { RequestMethod.GET })
	public void exportCommodity(HttpServletResponse response){
		ReturnBean<List<Commodity>> returnBean = iCommodityService.getCommodityByType("10", 1);
		List<Commodity> commodityList =  returnBean.getResult() != null ? returnBean.getResult() : new ArrayList<>();

		XSSFWorkbook wb;
		try {
			String basePath = ResourceUtils.getURL("classpath:").getPath();
			// excel模板路径
			String excel = basePath + "/static/excel/commodity.xlsx";
			File fi = new File(excel);
			// 读取excel模板
			wb = new XSSFWorkbook(new FileInputStream(fi));
			// 读取了模板内所有sheet内容
			XSSFSheet sheet = wb.getSheetAt(0);
			// 在相应的单元格进行赋值
			int rowIndex = 1;
			for (Commodity commodity : commodityList) {
				XSSFRow row = sheet.getRow(rowIndex);
				if (null == row) {
					row = sheet.createRow(rowIndex);
				}

				ExcelUtil.addCellValueForString(row, 0, commodity.getCommodityCode());
				ExcelUtil.addCellValueForString(row, 1, commodity.getCommodityName());
				ExcelUtil.addCellValueForString(row, 2, commodity.getCapacity());
				ExcelUtil.addCellValueForString(row, 3, commodity.getUnit());
				ExcelUtil.addCellValueForString(row, 4, String.valueOf(commodity.getPrice()));

				Brand brand = commodity.getBrand();
				ExcelUtil.addCellValueForString(row, 5, brand == null ? null : brand.getBrandName());
				ExcelUtil.addCellValueForString(row, 6, commodity.getCommodityTypeIDStr());
				ExcelUtil.addCellValueForString(row, 7, commodity.getSpecification());
//				ExcelUtil.addCellValueForString(row, 8, commodity.getRemark());

				rowIndex++;
			}

			String fileName = "商品列表";
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			wb.write(os);
			byte[] content = os.toByteArray();
			InputStream is = new ByteArrayInputStream(content);
			// 设置response参数，可以打开下载页面
			response.reset();
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xlsx").getBytes(), "iso-8859-1"));
			ServletOutputStream sout = response.getOutputStream();
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;

			try {
				bis = new BufferedInputStream(is);
				bos = new BufferedOutputStream(sout);
				byte[] buff = new byte[2048];
				int bytesRead;
				// Simple read/write loop.
				while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
					bos.write(buff, 0, bytesRead);
				}
			} catch (Exception e) {
				logger.error("导出excel出现异常:", e);
			} finally {
				if (bis != null) {
					bis.close();
				}
				if (bos != null) {
					bos.close();
				}
			}

		} catch (Exception e) {
			logger.error("导出excel出现异常:", e);
		}
	}

	/**
	 * 获取指定商品的所有渠道价格
	 *
	 * @param commodityID
	 */
	@ApiOperation(value = "获取指定商品的所有渠道价格", notes = "获取指定商品的所有渠道价格")
	@ApiImplicitParam(name = "commodityID", value = "商品ID", required = true, dataType = "String", paramType = "query")
	@RequestMapping(value = "/getCommodityChannelByID", method = { RequestMethod.GET })
	public ReturnBean<Commodity> getCommodityChannelByID(String commodityID){
		ReturnBean<Commodity> returnBean;

		String errorMessage = CommodityValidator.validateGetCommodityChannelByIDParams(commodityID);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.getCommodityChannelByID(commodityID);
		}
		return returnBean;
	}
	
	/**
	 * 获取指定商品信息，用于商品详情
	 * 
	 * 商品详情包括，商品 商品品牌 商品渠道 商品终端 及商品详情页图片展示
	 *
	 * @param commodityID
	 */
	@ApiOperation(value = "获取指定商品信息，用于商品详情", notes = "获取指定商品的所有渠道价格")
	@ApiImplicitParam(name = "commodityID", value = "商品ID", required = true, dataType = "String", paramType = "query")
	@RequestMapping(value = "/getCommodityByID", method = { RequestMethod.GET })
	public ReturnBean<Commodity> getCommodityByID(String commodityID){
		ReturnBean<Commodity> returnBean;

		String errorMessage = CommodityValidator.validateGetCommodityChannelByIDParams(commodityID);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.getCommodityByID(commodityID);
		}
		return returnBean;
	}

	/**
	 * 修改商品
	 * <ul>
	 * 	<li>修改时验证商品编码是否存在，如果存在则提示用户</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityDto
	 * @throws PinyinException 
	 */
	@ApiOperation(value = "修改商品", notes = "修改商品")
	@ApiImplicitParam(name = "commodityDto", value = "商品信息实体", required = true, dataType = "CommodityDto")
	@RequestMapping(value = "/updateCommodity", method = { RequestMethod.POST })
	public ReturnBean<Commodity> updateCommodity(@RequestBody  CommodityDto commodityDto) throws PinyinException{
		ReturnBean<Commodity> returnBean;

		String errorMessage = CommodityValidator.validateUpdateCommodityParams(commodityDto);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.updateCommodity(commodityDto);
		}
		return returnBean;
	}

	/**
	 * 修改商品渠道编码及价格
	 * <ul>
	 * 	<li>验证商品渠道编码是否重复</li>
	 * 	<li></li>
	 * </ul>
	 *
	 * @param commodityChannel
	 */
	@ApiOperation(value = "修改商品渠道编码及价格", notes = "修改商品渠道编码及价格")
	@ApiImplicitParam(name = "commodityChannel", value = "商品渠道实体", required = true, dataType = "commodityChannel")
	@RequestMapping(value = "/updateCommodityChannel", method = { RequestMethod.POST })
	public ReturnBean<CommodityChannel> updateCommodityChannel(@RequestBody CommodityChannel commodityChannel){
		ReturnBean<CommodityChannel> returnBean;

		String errorMessage = CommodityValidator.validateUpdateCommodityChannelParams(commodityChannel);
		if (errorMessage.length() > 0) {
			returnBean = new ReturnBean<>(-1, errorMessage);
		} else {
			returnBean = iCommodityService.updateCommodityChannel(commodityChannel);
		}
		return returnBean;
	}
	
	@ApiOperation(value = "获取所有渠道商品", notes = "获取所有渠道商品")
	@RequestMapping(value = "/getAllCommodityChannelList", method = { RequestMethod.POST })
	public ReturnBean<List<CommodityChannel>> getAllCommodityChannelList(){
		ReturnBean<List<CommodityChannel>> returnBean;
		returnBean = iCommodityChannelService.getAllCommodityChannelList() ;
		return returnBean;
	}
	
	@ApiOperation(value = "获取所有终端商品", notes = "获取所有终端商品")
	@ApiImplicitParams({@ApiImplicitParam(name = "commodityTerminalName", value = "商品名称", required = false, dataType = "String", paramType = "form"),
						@ApiImplicitParam(name = "pageNum", value = "第几页", required = false, dataType = "Integer", paramType = "form"),
						@ApiImplicitParam(name = "pageSize", value = "每页多少条", required = false, dataType = "Integer", paramType = "form")})
	@RequestMapping(value = "/getAllCommodityTerminal", method = { RequestMethod.POST })
	public ReturnBean<PageWrapper<CommodityTerminal>> getAllCommodityTerminalList(@RequestParam("commodityTerminalName")String commodityTerminalName,@RequestParam(defaultValue = "1", name = "pageNum") Integer pageNum,
			 @RequestParam(defaultValue = "20", name = "pageSize") Integer pageSize){
		
		return new ReturnBean<>(0, "获取所有终端商品成功", iCommodityTmlService.findAllCommodityTerminalByStatusAndHasCommodityTerminal(commodityTerminalName ,1 , 1 ,pageNum,  pageSize)) ; 
	}
	
	@ApiOperation(value = "获取所有终端商品视图", notes = "获取所有终端商品视图")
	@ApiImplicitParams({@ApiImplicitParam(name = "commodityTerminalName", value = "商品名称", required = false, dataType = "String", paramType = "form"),
						@ApiImplicitParam(name = "commodityTypeID", value = "商品类型ID", required = false, dataType = "String", paramType = "form"),
						@ApiImplicitParam(name = "pageNum", value = "第几页", required = false, dataType = "Integer", paramType = "form"),
						@ApiImplicitParam(name = "pageSize", value = "每页多少条", required = false, dataType = "Integer", paramType = "form")})
	@RequestMapping(value = "/getCommodityTerminalViewByPage", method = { RequestMethod.POST })
	public ReturnBean<PageWrapper<CommodityTerminalView>> getCommodityTerminalViewByPage(String commodityTerminalName, String commodityTypeID,
				@RequestParam(defaultValue = "1", name = "pageNum") Integer pageNum,
				@RequestParam(defaultValue = "20", name = "pageSize") Integer pageSize){
		
		return new ReturnBean<>(0, "获取所有终端商品成功", iCommodityTmlService.findAllCommodityTerminalViewByPage(commodityTerminalName, commodityTypeID, 1, 1, pageNum, pageSize)) ;
	}
	
	@ApiOperation(value = "获取所有品牌", notes = "获取所有品牌")
	@RequestMapping(value = "/findAllBrand", method = { RequestMethod.POST})
	@ResponseBody
	public ReturnBean<List<Brand>> findAllBrand() {
		return iBrandService.findAllBrandByStatus(1);
	}
	
	@ApiOperation(value = "获取久贸商品类型", notes = "获取久贸商品类型")
	@RequestMapping(value = "/findAllJiuMaoCommodityType", method = { RequestMethod.POST})
	@ResponseBody
	public ReturnBean<List<CommodityType>> findAllJiuMaoCommodityType() {
		return iCommodityTypeService.findJiuMaoCommodityType() ;
	}
	
	@ApiOperation(value = "获取久贸商品类型", notes = "获取久贸商品类型")
	@RequestMapping(value = "/findAllJiuMaoCommodityTypeByPage", method = { RequestMethod.POST})
	@ResponseBody
	public ReturnBean<PageWrapper<CommodityType>> findAllJiuMaoCommodityTypeByPage(String commodityTypeName ,Integer pageNum, Integer pageSize) {
		return  iCommodityTypeService.findJiuMaoCommodityTypeByPage(commodityTypeName , pageNum, pageSize) ;
	}
	
	@ApiOperation(value = "获取指定订单类型对应的渠道商品列表", notes = "获取指定订单类型对应的渠道商品列表")
	@RequestMapping(value = "/getCommodityChannelByOrderType", method = { RequestMethod.POST})
	@ResponseBody
	public ReturnBean<List<CommodityChannel>> getCommodityChannelByOrderType(String orderType) {
		return iCommodityChannelService.getCommodityChannelByOrderType(orderType) ;
	}
}
